//
// Created by dgy on 2022/11/11.
//

#include "server.h"
#include "player.h"

#include <sys/time.h>

int lastfireA = 0;
int lastfireB = 0;
char logfilename[128];

int ATurnFlag = 1;
int BTurnFlag = 1;

int playeratime = 0;
int playerbtime = 0;

int Judgement(int a[][M])//返回值为0代表 布局不符合规范 返回值为1代表符合规范
{
    int num1=0,num2=0,num3=0,num4=0,num5=0;
    //num1代表了驱逐舰所占格子的数量
    //num2代表了潜艇所占格子的数量
    //num3代表了巡洋舰所占格子的数量
    //num4代表了战列舰所占格子的数量
    //num5代表了航空母舰所占格子的数量
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<M;j++)
        {
            if(a[i][j]==D)
                num1++;
            if(a[i][j]==S)
                num2++;
            if(a[i][j]==C)
                num3++;
            if(a[i][j]==B)
                num4++;
            if(a[i][j]==A)
                num5++;
        }
    }
    if(num1!=2||num2!=3||num3!=3||num4!=4||num5!=5)
    {
        return 0;
    }
    int fd=1,fs=1,fc=1,fb=1,fa=1;
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<M;j++)
        {
            if((i<=M-2||j<=M-2)&&a[i][j]==D&&fd)
            {
                fd=0;
                if((i<=M-2&&a[i+1][j]!=D)&&(j<=M-2&&a[i][j+1]!=D))//找到第一个D  则如果下方和右边的不是D 则不符合条件
                {
                    return 0;
                }
            }
            if((i<=M-3||j<=M-3)&&a[i][j]==S&&fs)
            {
                fs=0;
                if(!(i<=M-3&&a[i+1][j]==S&&a[i+2][j]==S)
                   &&!(j<=M-3&&a[i][j+1]==S&&a[i][j+2]==S))
                    //找到第一个S 则 下方两个不同时是S 并且右方两个不同时是S  则不符合条件
                {
                    return 0;
                }
            }
            if((i<=M-3||j<=M-3)&&a[i][j]==C&&fc)
            {
                fc=0;
                if(!(i<=M-3&&a[i+1][j]==C&&a[i+2][j]==C)
                   &&!(j<=M-3&&a[i][j+1]==C&&a[i][j+2]==C))
                    //找到第一个C 则 下方两个不同时是C 并且右方两个不同时是C  则不符合条件
                {
                    return 0;
                }
            }

            if((i<=M-4||j<=M-4)&&a[i][j]==B&&fb)
            {
                fb=0;
                if(!(i<=M-4&&a[i+1][j]==B&&a[i+2][j]==B&&a[i+3][j]==B)
                   &&!(j<=M-4&&a[i][j+1]==B&&a[i][j+2]==B&&a[i][j+3]==B))
                    //找到第一个B 则 下方三个不同时是B 并且右方三个不同时是B  则不符合条件
                {
                    return 0;
                }
            }
            if((i<=M-5||j<=M-5)&&a[i][j]==A&&fa)
            {
                fa=0;
                if(!(i<=M-5&&a[i+1][j]==A&&a[i+2][j]==A&&a[i+3][j]==A&&a[i+4][j]==A)
                   &&!(j<=M-5&&a[i][j+1]==A&&a[i][j+2]==A&&a[i][j+3]==A&&a[i][j+4]==A))
                    //找到第一个A 则 下方四个不同时是A 并且右方四个不同时是A  则不符合条件
                {
                    return 0;
                }
            }
        }
    }
    return 1;
}

int ALastHitB()
{
    return lastfireA;
}

int BLastHitA()
{
    return lastfireB;
}

void firetoA(int i, int j)
{
    if(BTurnFlag)
    {
        DBGP(logfile, "%s fire to %s: (%d, %d)", PlayerBName, PlayerAName, i, j);
        if((PlayerA_BF.area[i][j] & 0x1) == 0)
        {
            PlayerA_BF.area[i][j] |= 1;
            lastfireB = 1;
            DBGP(logfile, "\tHit!!!");
        }
        else
        {
            lastfireB = 0;
        }
        DBGP(logfile, "\n");
    }
    BTurnFlag = 0;

    return ;
}

void firetoB(int i, int j)
{
    if(ATurnFlag)
    {
        DBGP(logfile, "%s fire to %s: (%d, %d)", PlayerAName, PlayerBName, i, j);
        if((PlayerB_BF.area[i][j] & 0x1) == 0)
        {
            PlayerB_BF.area[i][j] |= 1;
            lastfireA = 1;
            DBGP(logfile, "\tHit!!!");
        }
        else
        {
            lastfireA = 0;
        }
        DBGP(logfile, "\n");
    }
    ATurnFlag = 0;

    return ;
}

int main()
{
    struct timeval tvstart, tvend;
    int a, b;
    FILE * ALLBattleLog = NULL;

    sprintf(logfilename, "log/%s_vs_%s.log", PlayerAName, PlayerBName);
    logfile = fopen(logfilename, "w");

    ALLBattleLog = fopen("result.log", "a+");

    // 部署舰艇
    DBGP(logfile, "-------------%s---------------\n", PlayerAName);
    DeploymentA();
    DBGP(logfile, "-------------%s---------------\n", PlayerBName);
    DeploymentB();

    // 判断部署是否满足要求
    if(Judgement(PlayerA_BF.area)==0)
    {
        if(Judgement(PlayerB_BF.area)==0)
        {
            fprintf(ALLBattleLog, "%s(D) vs %s(D) Draw!\n", PlayerAName, PlayerBName);
            return 0;
        }
        else
        {
            fprintf(ALLBattleLog, "%s(D) vs %s Loss!\n", PlayerAName, PlayerBName);
            return 0;
        }
    }
    if(Judgement(PlayerB_BF.area)==0)
    {
        fprintf(ALLBattleLog, "%s vs %s(D) Win!\n", PlayerAName, PlayerBName);
        return 0;
    }

    // 轮流攻击
    int i = 1;
    while(1)
    {
        DBGP(logfile, "-------------%d---------------\n", i);
        a = isOver(&PlayerA_BF);
        b = isOver(&PlayerB_BF);
        if(a==1)
        {
            if(b==1)
                fprintf(ALLBattleLog, "%s vs %s Draw!\n", PlayerAName, PlayerBName);
            else
                fprintf(ALLBattleLog, "%s vs %s Loss!\n", PlayerAName, PlayerBName);
            break;
        }
        if(b==1)
        {
            fprintf(ALLBattleLog, "%s vs %s Win!\n", PlayerAName, PlayerBName);
            break;
        }
        // A's turn
        gettimeofday(&tvstart,NULL);
        ATurnFlag = 1;
        StrategyA();
        while(lastfireA==1)
        {
            ATurnFlag = 1;
            StrategyA();
        }
        gettimeofday(&tvend,NULL);
        playeratime += (tvend.tv_sec-tvstart.tv_sec)*1000000 + (tvend.tv_usec-tvstart.tv_usec);
        // B's turn
        BTurnFlag = 1;
        gettimeofday(&tvstart,NULL);
        StrategyB();
        while(lastfireB==1)
        {
            BTurnFlag = 1;
            StrategyB();
        }
        gettimeofday(&tvend,NULL);
        playerbtime += (tvend.tv_sec-tvstart.tv_sec)*1000000 + (tvend.tv_usec-tvstart.tv_usec);

        printALL(&PlayerA_BF, &PlayerB_BF);

        //sleep(1);
        i++;
        DBGP(logfile, "\n");


        if(i>=100)
        {
            fprintf(ALLBattleLog, "%s vs %s Draw!\n", PlayerAName, PlayerBName);
            break;
        }
    }
    DBGP(logfile, "\nplayera cost %d us\nplayerb cost %d us\n", playeratime, playerbtime);

    fclose(logfile);

    fclose(ALLBattleLog);

}
